/*
	Adobe Systems Incorporated(r) Source Code License Agreement
	Copyright(c) 2007 Adobe Systems Incorporated. All rights reserved.
	
	Please read this Source Code License Agreement carefully before using
	the source code.
	
	Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive, 
	no-charge, royalty-free, irrevocable copyright license, to reproduce,
	prepare derivative works of, publicly display, publicly perform, and
	distribute this source code and such derivative works in source or 
	object code form without any attribution requirements.  
	
	The name "Adobe Systems Incorporated" must not be used to endorse or promote products
	derived from the source code without prior written permission.
	
	You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
	against any loss, damage, claims or lawsuits, including attorney's 
	fees that arise or result from your use or distribution of the source 
	code.
	
	THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT 
	ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
	FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ALSO, THERE IS NO WARRANTY OF 
	NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT.  IN NO EVENT SHALL ADOBE
	OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
	OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package com.adobe.apps.ascension.localization
{
	import flash.system.Capabilities;
	import flash.filesystem.File;
	import flash.filesystem.FileStream;
	import flash.filesystem.FileMode;
	import flash.system.Capabilities;
	import com.adobe.utils.StringUtil;
	import flash.utils.describeType;
	
	/*
		Class to parse resource bundle xml file into LocaleResource value object
		for use throughout rest of the application.
	*/
	public class LocaleResourceParser
	{

		[Bindable]
		public var resource:LocaleResource;
	
		private var _locale:String;
		
		//default locale. If we cant determine the locale, or there is not
		//a resource bundle for the system locale, we default to this.
		private var _defaultLocale:String = "en";
		private var _localeDir:File = File.applicationResourceDirectory.resolvePath("locale");
		
		//This points to the root of the locale resource bundle directory being
		//used.
		//Use this to resolvePath any locale specifc paths.
		public var localeRoot:File;
		
		//the name of the main resource bundle file that contains localized 
		//name / value pairs
		public static const RESOURCE_FILE_NAME:String = "resource.xml";
		
		//constructor. Optionally takes a locale (to allow users to specify locale)
		public function LocaleResourceParser(locale:String = null)
		{
			if(locale == null)
			{
				_locale = Capabilities.language;
			}
			
			loadResources();
		}
		
		//this returns the root locale dir
		private function getLocaleDir():File
		{
			//get refernce to specified locale
			var f:File = _localeDir.resolvePath(_locale);
			
			//see if the bundle exists
			if(!f.exists)
			{
				//if it doesn;t default to default locale
				_locale = _defaultLocale;
				f = _localeDir.resolvePath(_locale);
			}
			
			return f;
		}
		
		//load and parse the resource bundle
		private function loadResources():void
		{
			//get the locale root dir
			var root:File = getLocaleDir();
			
			//get a reference to the resource file name
			var f:File = root.resolvePath(RESOURCE_FILE_NAME);
			
			//make sure the file is there, and it is an actual file
			if(!f.exists || f.isDirectory)
			{
				//wrong format.
				//todo: throw error?
				return;
			}
			
			//set the localeRoot property to point to the root
			localeRoot = root;
			
			//read in the locale resource file
			var fs:FileStream = new FileStream();
				fs.open(f, FileMode.READ);
			//read into a string
			var data:String = fs.readUTFBytes(fs.bytesAvailable);
				fs.close();
			
			//get the names of all of the properties in LocaleResources
			//we will use these to dynamically map them to the data in 
			//the resource file.
			var properties:Array = getPropertyNames();
			
			var x:XML = new XML(data);
			var l:LocaleResource = new LocaleResource();			
			
			var t:String;
			
			//loop through the locale properties
			for each(var n:String in properties)
			{
				//get the value from the locale resource XML
				t = StringUtil.trim(x[0].property.(@["name"] == n));
				
				if(t != "")
				{
					//make sure prop exists, if not, throw error
					//todo: validate it is correct xml
					l[n] = StringUtil.trim(x[0].property.(@["name"] == n));
				}
				else
				{
					//trace error for debugging
					trace("Localization Resource Property not set : LocaleResource." + n);
				}
			}
	
			resource = l;
				
			
		}
		
		//this function basically uses introspection to get the property names
		//that we need to populate from the resource locale file.
		private function getPropertyNames():Array
		{
			var c:Class = com.adobe.apps.ascension.localization.LocaleResource;
			
			//get an XML description of the locale value object.
			var xml:XML = describeType(c);
			
			//make sure to only accerrors that are declared in the class (not inheritted).
			//note, we have to use accerror, and not variable since Flex turns [Bindable]
			//variables into accesros [getter / setters]
			var props:XMLList = xml..accessor.(@["declaredBy"] == "com.adobe.apps.ascension.localization::LocaleResource");
			
			var out:Array = new Array();
			for each(var x:XML in props)
			{
				//push the names of the accesors into the array
				out.push(x.@name.toString());
			} 
			
			return out;
		}

	}
}
